import 'package:redux/redux.dart';
import '../models/chat_message_entity.dart';
import '../models/chat_conversation_entity.dart';
import '../data/default_chat_data.dart';

/// Redux聊天状态
class ReduxChatState {
  final List<ChatConversationEntity> conversationCollection;
  final String? activeConversationId;

  const ReduxChatState({
    this.conversationCollection = const [],
    this.activeConversationId,
  });

  ReduxChatState copyWith({
    List<ChatConversationEntity>? conversationCollection,
    String? activeConversationId,
  }) {
    return ReduxChatState(
      conversationCollection:
          conversationCollection ?? this.conversationCollection,
      activeConversationId: activeConversationId ?? this.activeConversationId,
    );
  }
}

/// Redux聊天动作
abstract class ReduxChatAction {}

class InitializeChatDataAction extends ReduxChatAction {
  final List<ChatConversationEntity> conversationList;
  InitializeChatDataAction(this.conversationList);
}

class SendTextMessageAction extends ReduxChatAction {
  final String conversationId;
  final String senderId;
  final String receiverId;
  final String content;
  SendTextMessageAction({
    required this.conversationId,
    required this.senderId,
    required this.receiverId,
    required this.content,
  });
}

class SendCallFailedMessageAction extends ReduxChatAction {
  final String conversationId;
  final String senderId;
  final String receiverId;
  SendCallFailedMessageAction({
    required this.conversationId,
    required this.senderId,
    required this.receiverId,
  });
}

class SetActiveConversationAction extends ReduxChatAction {
  final String conversationId;
  SetActiveConversationAction(this.conversationId);
}

class CreateNewConversationAction extends ReduxChatAction {
  final ChatConversationEntity newConversation;
  CreateNewConversationAction(this.newConversation);
}

class ClearConversationMessagesAction extends ReduxChatAction {
  final String conversationId;
  ClearConversationMessagesAction(this.conversationId);
}

/// Redux聊天Reducer
ReduxChatState chatReducer(ReduxChatState state, dynamic action) {
  if (action is InitializeChatDataAction) {
    return state.copyWith(conversationCollection: action.conversationList);
  }

  if (action is SendTextMessageAction) {
    final updatedConversations =
        state.conversationCollection.map((conv) {
          if (conv.conversationId == action.conversationId) {
            final newMessage = ChatMessageEntity(
              messageId: 'msg_${DateTime.now().millisecondsSinceEpoch}',
              conversationId: action.conversationId,
              senderId: action.senderId,
              receiverId: action.receiverId,
              messageType: ChatMessageType.textMessage,
              content: action.content,
              timestamp: DateTime.now(),
            );

            final updatedMessageList = List<ChatMessageEntity>.from(
              conv.messageList,
            )..add(newMessage);

            return conv.copyWith(
              messageList: updatedMessageList,
              lastMessageContent: action.content,
              lastMessageType: ChatMessageType.textMessage,
              lastMessageTime: DateTime.now(),
            );
          }
          return conv;
        }).toList();

    return state.copyWith(conversationCollection: updatedConversations);
  }

  if (action is SendCallFailedMessageAction) {
    final updatedConversations =
        state.conversationCollection.map((conv) {
          if (conv.conversationId == action.conversationId) {
            final newMessage = ChatMessageEntity(
              messageId: 'msg_${DateTime.now().millisecondsSinceEpoch}',
              conversationId: action.conversationId,
              senderId: action.senderId,
              receiverId: action.receiverId,
              messageType: ChatMessageType.callFailedMessage,
              content: 'Call failed',
              timestamp: DateTime.now(),
            );

            final updatedMessageList = List<ChatMessageEntity>.from(
              conv.messageList,
            )..add(newMessage);

            return conv.copyWith(
              messageList: updatedMessageList,
              lastMessageContent: 'Call failed',
              lastMessageType: ChatMessageType.callFailedMessage,
              lastMessageTime: DateTime.now(),
            );
          }
          return conv;
        }).toList();

    return state.copyWith(conversationCollection: updatedConversations);
  }

  if (action is SetActiveConversationAction) {
    return state.copyWith(activeConversationId: action.conversationId);
  }

  if (action is CreateNewConversationAction) {
    final updatedConversations = List<ChatConversationEntity>.from(
      state.conversationCollection,
    )..add(action.newConversation);
    return state.copyWith(conversationCollection: updatedConversations);
  }

  if (action is ClearConversationMessagesAction) {
    final updatedConversations =
        state.conversationCollection.map((conv) {
          if (conv.conversationId == action.conversationId) {
            return conv.copyWith(
              messageList: [],
              lastMessageContent: '',
              lastMessageType: null,
              lastMessageTime: DateTime.now(),
            );
          }
          return conv;
        }).toList();
    return state.copyWith(conversationCollection: updatedConversations);
  }

  return state;
}

/// Redux聊天服务
class ReduxChatManager {
  static final ReduxChatManager _instance = ReduxChatManager._internal();
  factory ReduxChatManager() => _instance;
  ReduxChatManager._internal();

  Store<dynamic>? _store;

  void initialize(Store<dynamic> store) {
    _store = store;
  }

  Store<dynamic> get store {
    if (_store == null) throw Exception('Chat service not initialized');
    return _store!;
  }

  void initializeChatData() {
    store.dispatch(
      InitializeChatDataAction(
        DefaultChatDataCollection.defaultConversationList,
      ),
    );
  }

  List<ChatConversationEntity> getAllConversations() =>
      List.from(store.state.chatState.conversationCollection);

  ChatConversationEntity? getConversationById(String conversationId) {
    try {
      return store.state.chatState.conversationCollection.firstWhere(
        (conv) => conv.conversationId == conversationId,
      );
    } catch (e) {
      return null;
    }
  }

  List<ChatMessageEntity> getMessagesByConversationId(String conversationId) {
    final conversation = getConversationById(conversationId);
    return conversation?.messageList ?? [];
  }

  String? getActiveConversationId() =>
      store.state.chatState.activeConversationId;

  void setActiveConversation(String conversationId) {
    store.dispatch(SetActiveConversationAction(conversationId));
  }

  Future<bool> sendTextMessage({
    required String conversationId,
    required String senderId,
    required String receiverId,
    required String content,
  }) async {
    try {
      await Future.delayed(const Duration(milliseconds: 300));
      store.dispatch(
        SendTextMessageAction(
          conversationId: conversationId,
          senderId: senderId,
          receiverId: receiverId,
          content: content,
        ),
      );
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> sendCallFailedMessage({
    required String conversationId,
    required String senderId,
    required String receiverId,
  }) async {
    try {
      await Future.delayed(const Duration(milliseconds: 200));
      store.dispatch(
        SendCallFailedMessageAction(
          conversationId: conversationId,
          senderId: senderId,
          receiverId: receiverId,
        ),
      );
      return true;
    } catch (e) {
      return false;
    }
  }

  Future<bool> createNewConversation(
    ChatConversationEntity newConversation,
  ) async {
    try {
      await Future.delayed(const Duration(milliseconds: 200));
      store.dispatch(CreateNewConversationAction(newConversation));
      return true;
    } catch (e) {
      return false;
    }
  }

  int getConversationCount() =>
      store.state.chatState.conversationCollection.length;

  List<ChatConversationEntity> getConversationsSortedByTime() {
    final conversations = List<ChatConversationEntity>.from(
      store.state.chatState.conversationCollection,
    );
    conversations.sort(
      (a, b) => b.lastMessageTime.compareTo(a.lastMessageTime),
    );
    return conversations;
  }

  Future<bool> clearConversationMessages(String conversationId) async {
    try {
      await Future.delayed(const Duration(milliseconds: 200));
      store.dispatch(ClearConversationMessagesAction(conversationId));
      return true;
    } catch (e) {
      return false;
    }
  }
}
